#include <util.h>
#include <qsort.h>
#include <heapsort.h>

#define _ARRAY_LEN ARRAY_LEN
#define _MY_RAND_MAX MY_RAND_MAX

int main(int argc, char *argv[])
{
    /*
    int a[] = {1, 3, 2};

    print_a(a, sizeof(a) / sizeof(a[0]));
    */
    //unsigned long long s, e, t;
    time_t t1, t2, t3, t4;
    int  i, j;
    // How to print a long long ?
    // long long repeat;
    long repeat;
    int a[_ARRAY_LEN];
    int b[_ARRAY_LEN];
    FILE *fqs, *fbs, *fhs;

    switch (argc)
    {
	case 2:
	    repeat = atoi(argv[1]);
	    break;
	case 3:
	    repeat = atoi(argv[1]) * atoi(argv[2]);
	    break;
	default:
	    repeat = REPEAT_TIME;
    }

    srand(time(NULL));
    for (i = 0; i < _ARRAY_LEN; i++)
    {
	b[i] = rand() % _MY_RAND_MAX;
    }
    print_a(b, _ARRAY_LEN, NULL);

    // quicksort
    t1 = time(NULL);
    fprintf(stdout, "t1: %lu\n", t1);
    for (j = 0; j < repeat; j++)
    {
	memcpy(a, b, sizeof(a));
	//quicksort(a, 0, _ARRAY_LEN - 1);
	quicksort_no_tail_recursion(a, 0, _ARRAY_LEN - 1);
    }
    t2 = time(NULL);
    fprintf(stdout, "t2: %lu\n", t2);
    //partition(a, 0, _ARRAY_LEN - 1);
    fprintf(stdout, "quicksort:\n");
    fqs = fopen("out.qs", "w");
    print_a(a, _ARRAY_LEN, fqs);

    // bubblesort
    for (j = 0; j < repeat; j++)
    {
	memcpy(a, b, sizeof(a));
	bubblesort(a, _ARRAY_LEN);
    }
    t3 = time(NULL);
    fprintf(stdout, "t3:%lu\n", t3);
    fprintf(stdout, "bubblesort:\n");
    fbs = fopen("out.bs", "w");
    print_a(a, _ARRAY_LEN, fbs);

    // heapsort
    for (j = 0; j < repeat; j++)
    {
	memcpy(a, b, sizeof(a));
	heapsort(a, _ARRAY_LEN);
    }
    t4 = time(NULL);
    fprintf(stdout, "t4:%lu\n", t4);
    fprintf(stdout, "heapsort:\n");
    fhs = fopen("out.hs", "w");
    print_a(a, _ARRAY_LEN, fhs);

    fprintf(stdout, "%ld times, t1(%lu), t2(%lu), t3(%lu), t4(%lu), "
	    "quicksort(%lu):bubblesort(%lu):heapsort(%lu)=%f:%f:%f\n", 
	    repeat, t1, t2, t3, t4, t2-t1, t3-t2, t4-t3,
	    (float)(t2-t1)/(t2-t1), (float)(t3-t2)/(t2-t1), (float)(t4-t3)/(t2-t1));

    return 0;
}
